package com.lonely.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.core.domain.Select;
import com.lonely.common.core.page.Condition;
import com.lonely.common.enums.CommonStatus;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.system.domain.dto.size.SysSizeLibraryPageQueryDto;
import com.lonely.system.domain.dto.size.SysSizeLibrarySubmitDto;
import com.lonely.system.domain.entity.SysSizeLibrary;
import com.lonely.system.domain.entity.SysSizeLibraryAssociation;
import com.lonely.system.domain.vo.system.size.SysSizeLibraryDetailVo;
import com.lonely.system.domain.vo.system.size.SysSizeLibraryPageQueryVo;
import com.lonely.system.mapper.SysSizeLibraryMapper;
import com.lonely.system.service.ISysSizeLibraryAssociationService;
import com.lonely.system.service.ISysSizeLibraryService;
import com.lonely.system.service.ISysSizeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : 黄志标
 * @date: 2025/7/29 9:56
 * @description: 尺码库服务实现类
 */
@Service
public class SysSizeLibraryServiceImpl extends ServiceImpl<SysSizeLibraryMapper, SysSizeLibrary> implements ISysSizeLibraryService {

    @Autowired
    private ISysSizeLibraryAssociationService sizeLibraryAssociationService;

    @Autowired
    private ISysSizeService sizeService;

    /**
     * 分页查询
     *
     * @param queryDto
     * @return
     */
    @Override
    public Page<SysSizeLibraryPageQueryVo> page(SysSizeLibraryPageQueryDto queryDto) {
        Page<SysSizeLibrary> page = Condition.page(queryDto);
        LambdaQueryWrapper<SysSizeLibrary> queryWrapper = new LambdaQueryWrapper<SysSizeLibrary>().like(StrUtil.isNotBlank(queryDto.getSizeLibraryName()), SysSizeLibrary::getSizeLibraryName, queryDto.getSizeLibraryName())
                .eq(queryDto.getStatus() != null, SysSizeLibrary::getStatus, queryDto.getStatus());

        Page<SysSizeLibrary> sizePage = super.page(page, queryWrapper);
        Page<SysSizeLibraryPageQueryVo> resultPage = new Page<>();
        BeanUtils.copyProperties(sizePage, resultPage);

        if (CollUtil.isNotEmpty(sizePage.getRecords())) {
            resultPage.setRecords(sizePage.getRecords().stream().map(x -> {
                SysSizeLibraryPageQueryVo sysSizeLibraryPageQueryVo = new SysSizeLibraryPageQueryVo();
                BeanUtils.copyProperties(x, sysSizeLibraryPageQueryVo);
                return sysSizeLibraryPageQueryVo;
            }).collect(Collectors.toList()));
        }
        return resultPage;
    }

    /**
     * 创建尺码库
     *
     * @param submitDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(SysSizeLibrarySubmitDto submitDto) {
        Assert.isNull(submitDto.getId(), "参数错误(id)");
        checkSizeLibrary(submitDto);

        SysSizeLibrary sysSizeLibrary = new SysSizeLibrary();
        BeanUtils.copyProperties(submitDto, sysSizeLibrary);
        sysSizeLibrary.setCreateBy(SecurityUtils.getUserId());
        sysSizeLibrary.setUpdateBy(SecurityUtils.getUserId());
        super.save(sysSizeLibrary);

        // 绑定尺码库与尺码的关系
        this.sizeLibraryAssociationService.bindSizeLibraryAndSize(sysSizeLibrary.getId(), submitDto.getSizeIds());
    }

    /**
     * 编辑尺码库
     *
     * @param submitDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SysSizeLibrarySubmitDto submitDto) {
        Assert.notNull(submitDto.getId(), "参数错误(id)");
        checkSizeLibrary(submitDto);
        SysSizeLibrary oldSizeLibrary = super.getById(submitDto.getId());
        BeanUtils.copyProperties(submitDto, oldSizeLibrary);
        oldSizeLibrary.setUpdateBy(SecurityUtils.getUserId());
        super.updateById(oldSizeLibrary);

        // 重新绑定尺码库与尺码的关系
        this.sizeLibraryAssociationService.bindSizeLibraryAndSize(oldSizeLibrary.getId(), submitDto.getSizeIds());
    }

    /**
     * 启用尺码库
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enabled(Long id) {
        SysSizeLibrary sysSizeLibrary = super.getById(id);
        Assert.notNull(sysSizeLibrary, "尺码库不存在");
        sysSizeLibrary.setStatus(CommonStatus.ENABLE.code);
        super.updateById(sysSizeLibrary);
    }

    /**
     * 禁用尺码库
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disable(Long id) {
        SysSizeLibrary sysSizeLibrary = super.getById(id);
        Assert.notNull(sysSizeLibrary, "尺码库不存在");
        sysSizeLibrary.setStatus(CommonStatus.DISABLE.code);
        super.updateById(sysSizeLibrary);
    }

    /**
     * 获取尺码库详情
     *
     * @param id
     * @return
     */
    @Override
    public SysSizeLibraryDetailVo getDetail(Long id) {
        SysSizeLibrary sysSizeLibrary = super.getById(id);
        Assert.notNull(sysSizeLibrary, "尺码库不存在");

        List<SysSizeLibraryAssociation> sysSizeLibraryAssociations = this.sizeLibraryAssociationService.list(new LambdaQueryWrapper<SysSizeLibraryAssociation>()
                .eq(SysSizeLibraryAssociation::getSizeLibraryId, id)
        );

        SysSizeLibraryDetailVo sysSizeLibraryDetailVo = new SysSizeLibraryDetailVo();
        sysSizeLibraryDetailVo.setId(id);
        sysSizeLibraryDetailVo.setSizeLibraryName(sysSizeLibrary.getSizeLibraryName());
        sysSizeLibraryDetailVo.setSizeIds(sysSizeLibraryAssociations.stream().map(SysSizeLibraryAssociation::getSizeId)
                .map(String::valueOf)
                .distinct().collect(Collectors.toList()));
        return sysSizeLibraryDetailVo;
    }

    /**
     * 获取尺码库下拉选项
     *
     * @return
     */
    @Override
    public List<Select> getSizeLibrarySelectOptions() {
        return super.list(new LambdaQueryWrapper<SysSizeLibrary>()
                .eq(SysSizeLibrary::getStatus, CommonStatus.ENABLE.code)
        ).stream().map(x -> {
            Select select = new Select();
            select.setValue(Convert.toStr(x.getId()));
            select.setLabel(x.getSizeLibraryName());
            return select;
        }).collect(Collectors.toList());
    }

    /**
     * 获取指定尺码库对应的商品尺码穿梭框选项值
     *
     * @param sizeLibraryId
     * @return
     */
    @Override
    public List<Select> getGoodsSizeTransferOptionsByLibrary(Long sizeLibraryId) {

        List<SysSizeLibraryAssociation> sysSizeLibraryAssociations = this.sizeLibraryAssociationService.list(new LambdaQueryWrapper<SysSizeLibraryAssociation>()
                .eq(SysSizeLibraryAssociation::getSizeLibraryId, sizeLibraryId)
        );

        if (CollUtil.isEmpty(sysSizeLibraryAssociations)) {
            return new ArrayList<>();
        }

        List<Long> sizeIds = sysSizeLibraryAssociations.stream().map(SysSizeLibraryAssociation::getSizeId).distinct().collect(Collectors.toList());
        return this.sizeService.listByIds(sizeIds).stream().map(x -> {
            Select select = new Select();
            select.setValue(x.getSizeName());
            select.setLabel(x.getSizeName());
            return select;
        }).collect(Collectors.toList());
    }


    /**
     * 校验尺码库信息
     *
     * @param submitDto
     */
    private void checkSizeLibrary(SysSizeLibrarySubmitDto submitDto) {

        // 1. 校验尺码名称是否重复
        int count = super.count(new LambdaQueryWrapper<SysSizeLibrary>()
                .eq(SysSizeLibrary::getSizeLibraryName, submitDto.getSizeLibraryName())
                .ne(submitDto.getId() != null, SysSizeLibrary::getId, submitDto.getId()));
        Assert.isTrue(count == 0, "该尺码库已存在");

        //2. 校验尺码库id是否正确
        if (submitDto.getId() != null) {
            SysSizeLibrary sysSizeLibrary = super.getById(submitDto.getId());
            Assert.notNull(sysSizeLibrary, "尺码库不存在");
        }
    }

}
